/* Testing gainCard function */

#include "dominion.h"
#include "dominion_helpers.h"
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "rngs.h"

// set TEST_OUTPUT to 0 to remove printfs from output
#define TEST_OUTPUT 0

int main() {
	int i;
	int seed = 100;
	int numPlayer = MAX_PLAYERS;
	int player;
	int toFlag;
	int gain;
	//From the example
	int k[10] = {adventurer, council_room, feast, gardens, mine, remodel, smithy, village, baron, great_hall};
	struct gameState G;
	struct gameState G_before;
	//Taken from the example testUpdateCoins.c, but still quite necessary.
	memset(&G, 23, sizeof(struct gameState));   			// clear the game state
    initializeGame(numPlayer, k, seed, &G); 			// initialize a new game
	memcpy(&G_before, &G, sizeof(struct gameState));		//Copy the initialized game state for future reference and state adjustment.
	
	for (player = 0; player < numPlayer; ++player)
	{
		for (toFlag = 0; toFlag < 3; ++toFlag)
		{
			for (i = 0; i < (treasure_map +1); ++i)
			{
				memcpy(&G_before, &G, sizeof(struct gameState));	
				if (TEST_OUTPUT) printf("\nTesting gainCard player %d, toFlag %d, card(i) %d, supplyCount %d\n", player, toFlag, i, supplyCount(i, &G));
				//First check for unused supply cards and make sure gainCard exits early
				if (supplyCount(i, &G) < 1)
				{
					gain = gainCard(i, &G, toFlag, player);	//Because gain effects supplyCount, we needed to make the check first to see if gain should go -1, then perform gain and assert that.
					if (TEST_OUTPUT) printf("\ngain = %d\n", gain);
					assert(gain == -1);
				} else {
					gain = gainCard(i, &G, toFlag, player);
					//Depending on the flag, we need to make sure the game state is updated correctly
					if (toFlag == 1)
					{
						if (TEST_OUTPUT) printf("G.deckCount[player] = %d G.deck[player][G.deckCount[player]] = %d\n", G.deckCount[player] - 1, G.deck[player][G.deckCount[player] - 1]);
						assert(G.deck[player][G.deckCount[player] - 1] == i);
						assert(G.deckCount[player] == (G_before.deckCount[player] + 1));
						assert(G.handCount[player] == G_before.handCount[player]);
						assert(G.discardCount[player] == G_before.discardCount[player]);
					} else if (toFlag == 2) {
						if (TEST_OUTPUT) printf("G.handCount[player] = %d G.hand[player][G.handCount[player]] = %d\n", G.handCount[player] - 1, G.hand[player][G.handCount[player] - 1]);
						assert(G.hand[player][G.handCount[player] - 1] == i);
						assert(G.handCount[player] == (G_before.handCount[player] + 1));
						assert(G.discardCount[player] == G_before.discardCount[player]);
						assert(G.deckCount[player] == G_before.deckCount[player]);
					} else {
						if (TEST_OUTPUT) printf("G.discardCount[player] = %d G.discard[player][G.discardCount[player]] = %d\n", G.discardCount[player] - 1, G.discard[player][G.discardCount[player] - 1]);
						assert(G.discard[player][G.discardCount[player] - 1] == i);
						assert(G.discardCount[player] == (G_before.discardCount[player] + 1));
						assert(G.handCount[player] == G_before.handCount[player]);
						assert(G.deckCount[player] == G_before.deckCount[player]);
					}
					//Finally we need to make sure the supply pile is decreased from where it was.
					assert(G.supplyCount[i] == (G_before.supplyCount[i] - 1));
				}
			}
		}
	}

	printf("Unittest3: All Tests Passed!\n");
	return 0;
}